home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 April / EnigmA AMIGA RUN 17 (1997)(G.R. Edizioni)(IT)[!][issue 1997-04][EAR-CD].iso / EARCD / text / hyper / hsc_source.lha / hsc / source / hsclib / uri.c < prev    next >
C/C++ Source or Header  |  1996-12-04  |  12KB  |  455 lines

  1. /*
  2.  * uri.c
  3.  *
  4.  * functions for uri parsing of tag arguments
  5.  *
  6.  * Copyright (C) 1995,96  Thomas Aglassinger
  7.  *
  8.  * This program is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; either version 2 of the License, or
  11.  * (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU General Public License
  19.  * along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  *
  22.  * updated:  4-Dec-1996
  23.  * created: 16-Jul-1995
  24.  */
  25.  
  26. #define NOEXTERN_HSCLIB_URI_H
  27.  
  28. #include "ugly/fname.h"
  29.  
  30. #include "hsclib/inc_base.h"
  31. #include "hsclib/idref.h"
  32. #include "hscprj/project.h"
  33. #include "hsclib/uri.h"
  34.  
  35. #define PARENT_URI "../"        /* string for parent dir within URIs */
  36.  
  37. #define weenix jens /* TODO:remove this */
  38.  
  39. /*
  40.  * conv_path2uri
  41.  *
  42.  * convert a path for local (system-dependant)
  43.  * file system to URI
  44.  */
  45. VOID conv_path2uri(EXPSTR * dest, STRPTR path)
  46. {
  47.     clr_estr(dest);
  48.  
  49. #ifdef AMIGA
  50.     /* replace leading parent directories by "../" */
  51.     while (!strncmp(path, PARENT_DIR, strlen(PARENT_DIR)))
  52.     {
  53.         app_estr(dest, PARENT_URI);
  54.         path += strlen(PARENT_DIR);
  55.     }
  56.  
  57.     while (path[0])
  58.     {
  59.         /* replace all "//" by "../" */
  60.         if ((path[0] == '/') && (path[1] == '/'))
  61.         {
  62.             app_estr(dest, PARENT_URI);
  63.             path += 2;
  64.         }
  65.         else
  66.         {
  67.             app_estrch(dest, path[0]);
  68.             path++;
  69.         }
  70.     }
  71.  
  72. #elif defined MSDOS
  73.     /* replace "\" by "/" */
  74.     while (path[0])
  75.     {
  76.         if ((path[0] == '\\'))
  77.             app_estrch(dest, '/');
  78.         else
  79.             app_estrch(dest, path[0]);
  80.         path++;
  81.     }
  82.  
  83. #elif defined UNIX
  84.     /* simply copy path */
  85.     set_estr(dest, path);
  86. #else
  87. #error "system not supported: conv_path2uri"
  88. #endif
  89. }
  90.  
  91. /*
  92.  * conv_uri2path
  93.  *
  94.  * convert a uri to a path for local (system-dependant)
  95.  * file system
  96.  */
  97. VOID conv_uri2path(EXPSTR * dest, STRPTR uri, BOOL weenix)
  98. {
  99.     clr_estr(dest);
  100.  
  101. #ifdef AMIGA
  102.     if (weenix)
  103.     {
  104.         /* convert leading "/" to ":" */
  105.         /* convert leading "~" to ":" */
  106.         if (!strncmp(uri, "/", 1)
  107.             || !strncmp(uri, "~/", 2)
  108.             || !strncmp(uri, "~", 1))
  109.         {
  110.             app_estr(dest, ":");
  111.             uri++;
  112.         }
  113.     }
  114.  
  115.     /* convert leading "../" to "/" */
  116.     while (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  117.     {
  118.         app_estr(dest, PARENT_DIR);
  119.         uri += strlen(PARENT_URI);
  120.     }
  121.  
  122.     /* convert inside "../" to "//" */
  123.     while (uri[0])
  124.     {
  125.         if (!strncmp(uri, PARENT_URI, strlen(PARENT_URI)))
  126.         {
  127.             app_estrch(dest, '/');
  128.             uri += strlen(PARENT_URI);
  129.         }
  130.         else
  131.         {
  132.             app_estrch(dest, uri[0]);
  133.             uri++;
  134.         }
  135.     }
  136.  
  137. #elif defined MSDOS
  138.     /* replace "\" by "/" */
  139.     while (uri[0])
  140.     {
  141.         if (uri[0] == '/')
  142.             app_estrch(dest, '\\');
  143.         else
  144.             app_estrch(dest, uri[0]);
  145.         uri++;
  146.     }
  147.  
  148. #elif defined UNIX
  149.     set_estr(dest, uri);
  150. #else
  151. #error "system not supported: conv_uri2path"
  152. #endif
  153. }
  154.  
  155. /*
  156.  * uri_kind
  157.  *
  158.  * evaluate kind of uri
  159.  */
  160. URIKIND uri_kind(STRPTR uri)
  161. {
  162.     URIKIND kind = URI_abs;
  163.  
  164.     if (upstrncmp(uri, ABSURI_ID, strlen(ABSURI_ID)))
  165.     {
  166.         if (uri[0] == '/')
  167.             kind = URI_relserv;
  168.         else
  169.         {
  170.             STRPTR colon_pos = strchr(uri, ':');
  171.             STRPTR slash_pos = strchr(uri, '/');
  172.  
  173.             if (colon_pos)
  174.                 if (slash_pos)
  175.                     if (colon_pos < slash_pos)
  176.                         kind = URI_ext;
  177.                     else
  178.                         kind = URI_rel;
  179.                 else
  180.                     kind = URI_ext;
  181.             else
  182.                 kind = URI_rel;
  183.         }
  184.     }
  185.     return (kind);
  186. }
  187.  
  188. /*
  189.  * convert uri to filename in destination-dir
  190.  */
  191. static VOID conv_hscuri2fileNuri(HSCPRC * hp, EXPSTR * dest_uri, EXPSTR * dest_fname, STRPTR uri)
  192. {
  193.     EXPSTR *rel_path = init_estr(32);   /* relative path */
  194.     URIKIND kind = uri_kind(uri);
  195.  
  196.     clr_estr(dest_uri);
  197.     clr_estr(dest_fname);
  198.  
  199.     /* if a <BASE HREF=".."> was found before,
  200.      * therefor treat URI as absolute
  201.      */
  202.     if (hp->docbase_set)
  203.         kind = URI_ext;
  204.  
  205.     /* evaluate kind of URI */
  206.     if (kind == URI_abs)
  207.         uri++;                  /* skip ":" */
  208.  
  209.     /* reset destination filename */
  210.     set_estr(dest_fname, "");
  211.  
  212.     if (kind == URI_abs)
  213.     {
  214.         /*
  215.          * parse absolute uri
  216.          */
  217.         D(fprintf(stderr, DHL "exists `%s' [abs]\n", uri));
  218.  
  219.         /* check if local uri exists */
  220.         {
  221.             EXPSTR *dest_relfname = init_estr(32);
  222.             conv_uri2path(dest_relfname, uri, hp->weenix);
  223.  
  224.             estrcpy(dest_fname, hp->destdir);
  225.             estrcat(dest_fname, dest_relfname);
  226.  
  227.             del_estr(dest_relfname);
  228.         }
  229.  
  230.         D(fprintf(stderr, DHL "  -> file `%s'\n",
  231.                   estr2str(dest_fname)));
  232.  
  233.         /* create path of destination file */
  234.         estrcpy(dest_uri, hp->reldir);
  235.         app_estr(dest_uri, uri);
  236.  
  237.         get_relfname(rel_path, uri, estr2str(hp->reldir));
  238.         D(fprintf(stderr, DHL "  -> rel. path `%s' (`%s')\n",
  239.                   estr2str(rel_path),
  240.                   estr2str(hp->reldir)));
  241.  
  242.         /* debug */
  243.         D(fprintf(stderr, DHL "  -> real path `%s'\n", uri));
  244.  
  245.         /* convert (filesystem depending) path to uri */
  246.         conv_path2uri(dest_uri, estr2str(rel_path));
  247.  
  248.         /* debug */
  249.         D(fprintf(stderr, DHL "  -> real uri  `%s'\n",
  250.                   estr2str(dest_uri)));
  251.     }
  252.     else if (kind == URI_rel)
  253.     {
  254.         /*
  255.          * parse relative uri
  256.          */
  257.         EXPSTR *uri_path = init_estr(32);
  258.  
  259.         /* debug */
  260.         D(fprintf(stderr, DHL "exists `%s' [rel]\n", uri));
  261.  
  262.         /* create local filename */
  263.         conv_uri2path(uri_path, uri, hp->weenix);
  264.         estrcat(dest_fname, hp->destdir);
  265.         estrcat(dest_fname, hp->reldir);
  266.         estrcat(dest_fname, uri_path);
  267.  
  268.         /* create uri (only copy path) */
  269.         set_estr(dest_uri, uri);
  270.  
  271.         /* debug */
  272.         D(
  273.              {
  274.              fprintf(stderr, DHL "  -> real path `%s'\n",
  275.                      estr2str(dest_fname));
  276.              fprintf(stderr, DHL "  -> real uri  `%s'\n",
  277.                      estr2str(dest_uri));
  278.              }
  279.         );
  280.  
  281.         del_estr(uri_path);
  282.     }
  283.     else
  284.     {
  285. #if 0
  286.         STRARR tmp[300];
  287.  
  288.         strcpy(tmp, "unknown uri-kind: ");
  289.         strcat(tmp, uri);
  290.         panic(tmp);
  291. #endif
  292.         set_estr(dest_uri, uri);
  293.         set_estr(dest_fname, "");
  294.     }
  295.  
  296.     /* free resources */
  297.     del_estr(rel_path);
  298. }
  299.  
  300. VOID conv_hscuri2file(HSCPRC * hp, EXPSTR * dest_fname, STRPTR uri)
  301. {
  302.     EXPSTR *dest_uri = init_estr(64);
  303.     conv_hscuri2fileNuri(hp, dest_uri, dest_fname, uri);
  304.     del_estr(dest_uri);
  305. }
  306.  
  307. /*
  308.  * parse_uri
  309.  *
  310.  * check uri-string for syntatic correctnes;
  311.  * if the uri refers to an local file, convert its absolute
  312.  * path to a relative path and check its existence.
  313.  *
  314.  * uri = "rsrc_type://host.domain:port/pathname#id"
  315.  */
  316. VOID parse_uri(HSCPRC * hp, EXPSTR * dest_uri, STRPTR uri)
  317. {
  318.     STRPTR host = NULL;
  319.     STRPTR port = NULL;
  320.     STRPTR path = NULL;
  321.     STRPTR name = NULL;
  322.  
  323.     clr_estr(dest_uri);
  324.  
  325.     if (uri)
  326.     {
  327.         /* check for valid uri */
  328.         URIKIND kind = uri_kind(uri);
  329.         if ((kind == URI_ext) || (kind == URI_relserv))
  330.         {
  331.             if (kind == URI_ext)
  332.             {
  333.                 /*
  334.                  * check global uri
  335.                  */
  336.                 if (!host)
  337.                     host = "";
  338.                 if (!port)
  339.                     port = "";
  340.                 if (!host)
  341.                     host = "";
  342.  
  343.                 /*
  344.                  * TODO: parse global uris
  345.                  */
  346.             }
  347.             set_estr(dest_uri, uri);
  348.         }
  349.         else
  350.         {
  351.             /*
  352.              * check local uri
  353.              */
  354.  
  355.             /* destination file name that's existence is checked if
  356.              * chkuri is enabled */
  357.             EXPSTR *dest_fname = init_estr(32);
  358.             STRPTR noabsuri = uri;
  359.  
  360.             /* evaluate kind of URI */
  361.             if (kind == URI_abs)
  362.                 noabsuri++;     /* skip ":" */
  363.  
  364.             /* extract path and #name */
  365.             if (noabsuri[0] == '#')
  366.             {
  367.                 path = NULL;
  368.                 name = noabsuri + 1;    /* skip '#' for ":#id" */
  369.             }
  370.             else
  371.             {
  372.                 path = strtok(uri, "#");
  373.                 name = strtok(NULL, "");
  374.             }
  375.  
  376.             if (path)
  377.             {
  378.                 FILE *exist = NULL;
  379.  
  380.                 /*
  381.                  * check existence of local uri
  382.                  */
  383.                 conv_hscuri2fileNuri(hp, dest_uri, dest_fname, path);
  384.                 if (hp->chkuri
  385.                     && !(hsc_get_msg_ignore(hp, MSG_NO_URIPATH)))
  386.                 {
  387.                     exist = fopen(estr2str(dest_fname), "r");
  388.                     if (!exist)
  389.                     {
  390.                         hsc_msg_nouri(hp, estr2str(dest_fname), uri, NULL);
  391.                     }
  392.                     else
  393.                     {
  394.                         fclose(exist);
  395.  
  396.                         /* check id */
  397.                         if (hp->chkid && name)
  398.                         {
  399.                             STRPTR doc_fname = estr2str(dest_fname);
  400.  
  401.                             if (!fnamecmp(hp->project->document->docname,
  402.                                           doc_fname))
  403.                             {
  404.                                 /* filename references current document */
  405.                                 add_local_idref(hp, name);
  406.                             }
  407.                             else
  408.                             {
  409.                                 /* filename reference other document;
  410.                                  * lookup project-data */
  411.                                 switch (check_document_id(hp->project,
  412.                                                           doc_fname, name))
  413.                                 {
  414.                                 case ERR_CDI_OK:
  415.                                     D(fprintf(stderr, DHL "  id ok\n"));
  416.                                     break;
  417.                                 case ERR_CDI_NoID:
  418.                                     hsc_msg_unknown_id(hp, NULL, name);
  419.                                     break;
  420.                                 case ERR_CDI_NoDocumentEntry:
  421.                                     hsc_message(hp, MSG_NO_DOCENTRY,
  422.                                                 "no entry for document %q "
  423.                                               "in project data to check %i",
  424.                                                 estr2str(dest_fname),
  425.                                                 name);
  426.                                     break;
  427.                                 default:
  428.                                     panic("unknown returncode");
  429.                                     break;
  430.                                 }
  431.                             }
  432.                         }
  433.                     }
  434.                 }
  435.             }
  436.             else
  437.             {
  438.                 /* check existence ID referencing into current file */
  439.                 if (hp->chkid && name)
  440.                     add_local_idref(hp, name);
  441.             }
  442.  
  443.             /* add #name part */
  444.             if (name)
  445.             {
  446.                 app_estrch(dest_uri, '#');
  447.                 app_estr(dest_uri, name);
  448.             }
  449.             /* free resources */
  450.             del_estr(dest_fname);
  451.         }                       /* else (rsrc) */
  452.     }                           /* if (uri) */
  453. }
  454.  
  455.